from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
from utils import get_max, get_min, get_prev_item, get_next_item

def cache_method_value(func):
    name = '_cache_%s' % func.__name__
    def decorated(self, *args, **kwargs):
        if not hasattr(self, name):
            setattr(self, name, func(self, *args, **kwargs))
        return getattr(self, name)
    return decorated

class OrderingModel(models.Model):
    order = models.PositiveIntegerField(_('order'), default=0, editable=False)

    def objects_filter(self):
        return self.__class__.objects.all()

    @cache_method_value
    def is_first(self):
        return self.order == get_min(self.objects_filter(), 'order')

    @cache_method_value
    def is_last(self):
        return self.order == get_max(self.objects_filter(), 'order')

    @cache_method_value
    def prev(self):
        return get_prev_item(self.objects_filter(), 'order', self.order)

    @cache_method_value
    def next(self):
        return get_next_item(self.objects_filter(), 'order', self.order)

    def adm_move_up_link(self):
        if self.is_first():
            return ''
        else:
            return 'move_up/%s/' % self.pk

    def adm_move_down_link(self):
        if self.is_last():
            return ''
        else:
            return 'move_down/%s/' % self.pk

    def adm_move_up(self):
        link = self.adm_move_up_link()
        return link and '<a href="%s" style="white-space:nowrap"><img src="%simg/admin/arrow-up.gif" border="0"> %s</a>' % (link, settings.ADMIN_MEDIA_PREFIX, _('up')) or ''
    adm_move_up.allow_tags = True
    adm_move_up.short_description = ''

    def adm_move_down(self):
        link = self.adm_move_down_link()
        return link and '<a href="%s" style="white-space:nowrap"><img src="%simg/admin/arrow-down.gif" border="0"> %s</a>' % (link, settings.ADMIN_MEDIA_PREFIX, _('down')) or ''
    adm_move_down.allow_tags = True
    adm_move_down.short_description = ''

    class Meta:
        abstract = True
        ordering = ('order',)

